import qs from 'qs'
import axios from 'axios'
import store from '@/store'
import { Message } from 'element-ui'
import router from '@/router'

const request = axios.create({

})

function redirectLogin () {
  router.push({
    name: 'login',
    query: {
      redirect: router.currentRoute.fullPath
    }
  })
}

function refreshToken () {
  return axios.create()({
    method: 'POST',
    url: '/front/user/refresh_token',
    data: qs.stringify({
      refreshtoken: store.state.user.refresh_token
    })
  })
}

// 请求拦截器
request.interceptors.request.use(function (config) {
  // 通过改写 config 配置信息进行业务功能统一管理
  const { user } = store.state
  if (user && user.access_token) {
    config.headers.Authorization = user.access_token
  }
  return config
}, function (error) {
  return Promise.reject(error)
})

// 响应拦截器
let isRefreshing = false
let requests: any[] = []
request.interceptors.response.use(function (response) {
  return response
}, async function (error) {
  if (error.response) {
    // 请求发出受到响应，但是状态码超出2xx
    const { status } = error.response
    if (status === 400) {
      Message.error('请求参数错误')
    } else if (status === 401) {
      // token 无效 （没有提供 token、token 是无效的、token过期了）
      // 如果有 refresh_token 则尝试使用 refresh_token 获取新的 access_token
      if (!store.state.user) {
        redirectLogin()
      }

      // 尝试刷新获取新的 token
      if (!isRefreshing) {
        isRefreshing = true
        return refreshToken().then(res => {
          if (!res.data.success) {
            throw new Error('刷新 Token 失败')
          }

          // 刷新 token 成功了
          store.commit('setUser', res.data.content)
          // 把 request 队列中的请求重新发送出去
          requests.forEach(cb => cb())
          // 重置 request 数组
          requests = []
          return request(error.config)
        }).catch(err => {
          console.log(err)
          store.commit('setUser', null)
          redirectLogin()
          return Promise.reject(error)
        }).finally(() => {
          isRefreshing = false
        })
      }

      // 刷新状态下，把请求挂起放到 requests 数组中
      return new Promise(resolve => {
        requests.push(() => {
          resolve(request(error.config))
        })
      })
      // try {
      //   const { data } = await axios.create()({
      //     method: 'POST',
      //     url: '/front/user/refresh_token',
      //     data: qs.stringify({
      //       refreshtoken: store.state.user.refresh_token
      //     })
      //   })
      //   //  成功了 ——> 把本次失败的请求重新发出去
      //   //  把刷新拿到的新的 access_token 更新到容器和本地存储中
      //   store.commit('setUser', data.content)
      //   // 发送本次失败的请求
      //   return request(error.config)
      // } catch (error) {
      //   store.commit('setUser', null)
      //   //  失败了 ——> 跳转登录页面重新获取新的 token
      //   redirectLogin()
      //   return Promise.reject(error)
      // }
      //  如果没有，直接跳转登录页面
    } else if (status === 403) {
      Message.error('请求资源不存在')
    } else if (status >= 500) {
      Message.error('服务端错误，请联系管理员')
    }
  } else if (error.request) {
    // 请求发出未响应
    Message.error('请求超时，请刷新重试')
  } else {
    // 在设置上发生了一些事情，触发了一个错误
    Message.error(`请求失败：${error.message}`)
  }

  // 抛出请求失败的错误对象，扔给下一个上一个调用者
  return Promise.reject(error)
})

export default request
